public class ProducerCustomDemo {
    public static void main(String[] args) {
        Food food = new Food();
        Producer producer = new Producer(food);
        Customers customers = new Customers(food);
        Thread thread = new Thread(producer);
        Thread thread1 = new Thread(customers);
        //java本身就是多线程的，thread和thread1在互相抢CPU时间片
        thread.start();
        thread1.start();
    }
}

//食物
class Food {
    private String name;
    private String desc;

    //true表示可以生产，false表示可以消费
    private boolean flag = true;

    public Food() {
    }

    public Food(String name, String desc) {
        this.name = name;
        this.desc = desc;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }

    //输出对象new Food()时，如System.out.println(new Food());按下面的格式输出。如果没写就输出对想的哈希值。
    @Override
    public String toString() {
        return "Food{" +
                "name='" + name + '\'' +
                ", desc='" + desc + '\'' +
                '}';
    }

    //生产产品
    public synchronized void set(String name, String desc) {
        //不能生产
        if(!flag){
            try {
                //wait()：线程进入等待状态，释放监视器的所有权（对象锁）。
                //等待被其他线程唤醒notify()。
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        this.setName(name);
        //sleep()模拟生产所需时间
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        this.setDesc(desc);
        flag = !flag;
        //唤醒等待的线程（随机的其中一个,只有两个就是另一个。）
        this.notify();
    }

    //消费产品
    public synchronized void get() {
        //不能消费
        if(flag){
            try {
                //线程进入等待状态，释放监视器的所有权（对象锁）
                //等待被唤醒notify()
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(this.getName() + "->" + this.getDesc());
        flag = !flag;
        this.notify();
    }
}

//生产者：生产Food
class Producer implements Runnable {
    private Food food;

    public Producer(Food food) {
        this.food = food;
    }

    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            if (i % 2 == 0) {
                food.set("菜品1", "口味1");
            } else {
                food.set("菜品2", "口味2");
            }
        }
    }
}

//消费者
class Customers implements Runnable {
    private Food food;

    public Customers(Food food) {
        this.food = food;
    }

    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            food.get();
        }
    }
}
